package org.aspectsense.middleware.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeSelectionModel;


public class MainFrame extends JFrame {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JPanel MainPanel = null;
	private JPanel taskBar = null;
	private JMenu mainMenu = null;
	private JTabbedPane mainTabbedPane = null;
	private JPanel monitorPanel = null;
	private JScrollPane monitorTabScrollPane = null;
	private JScrollPane monitorTabDescScroll = null;
	private JEditorPane monitorTabDescTextArea = null;
	private JTree monitorTabTree = null;
	private DefaultMutableTreeNode root = null;  
	private DefaultMutableTreeNode componentsRoot = null;  //  @jve:decl-index=0:
	private DefaultMutableTreeNode servicesRoot = null;  //  @jve:decl-index=0:
	private DefaultTreeModel myTreeModel;
	private static JPanel graphPanel = null;
	private JPanel graphContainer = null;
	private JPanel graphTaskBar = null;
	private JButton maxPathsButton = null;
	private JButton refreshButton = null;
	private JButton showTree = null;
	private ITreeNode activeNode = null;
	private JPanel graphOverviewContainer;
	private static JPanel graphOverviewPanel;
	private JScrollPane graphOverviewScrollPane = null;
	private JButton overviewShowMaxButton;
	private JPanel graphOverviewTaskBar = null;
	private JButton maxPaths = null;
	
	/**
	 * This is the default constructor
	 */
	public MainFrame() {
		super();
		initialize();
	}
	



	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
	
		this.setSize(300, 200);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setContentPane(getJContentPane());
		this.setTitle("AspectSense");
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getTaskBar(), BorderLayout.SOUTH);
			jContentPane.add(getMainPanel(), BorderLayout.CENTER);
			
			jContentPane.add(getMainMenu(), BorderLayout.NORTH);
		}
		return jContentPane;
	}

	/**
	 * This method initializes MainPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getMainPanel() {
		if (MainPanel == null) {
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.fill = GridBagConstraints.BOTH;
			gridBagConstraints.gridy = 0;
			gridBagConstraints.weightx = 1.0;
			gridBagConstraints.weighty = 1.0;
			gridBagConstraints.gridx = 0;
			MainPanel = new JPanel();
			MainPanel.setLayout(new GridBagLayout());
			MainPanel.add(getMainTabbedPane(), gridBagConstraints);
		}
		return MainPanel;
	}

	/**
	 * This method initializes taskBar	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getTaskBar() {
		if (taskBar == null) {
			taskBar = new JPanel();
			taskBar.setLayout(new BoxLayout(getTaskBar(), BoxLayout.X_AXIS));
			taskBar.add(getShowTree(), null);
		}
		return taskBar;
	}

	/**
	 * This method initializes mainMenu	
	 * 	
	 * @return javax.swing.JMenu	
	 */
	private JMenu getMainMenu() {
		if (mainMenu == null) {
			mainMenu = new JMenu();
		}
		return mainMenu;
	}

	/**
	 * This method initializes mainTabbedPane	
	 * 	
	 * @return javax.swing.JTabbedPane	
	 */
	private JTabbedPane getMainTabbedPane() {
		if (mainTabbedPane == null) {
			mainTabbedPane = new JTabbedPane();
			mainTabbedPane.setToolTipText("");
			mainTabbedPane.setName("Monitor");
			mainTabbedPane.addTab("Monitor", null, getMonitorPanel(), "Displays a hierarchical view of AspectSense elements");
			mainTabbedPane.addTab("Overview", null, getGraphOverviewScrollPane(), null);
			
			
		}
		return mainTabbedPane;
	}

	/**
	 * This method initializes monitorPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getMonitorPanel() {
		if (monitorPanel == null) {
			monitorPanel = new JPanel();
			monitorPanel.setLayout(new BoxLayout(getMonitorPanel(), BoxLayout.X_AXIS));
			monitorPanel.setPreferredSize(new Dimension(250, 403));
			monitorPanel.add(getMonitorTabScrollPane(), null);
			monitorPanel.add(getMonitorTabDescScroll(), null);
		}
		return monitorPanel;
	}

	/**
	 * This method initializes monitorTabScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getMonitorTabScrollPane() {
		if (monitorTabScrollPane == null) {
			monitorTabScrollPane = new JScrollPane();
			monitorTabScrollPane.setPreferredSize(new Dimension(99, 403));
			monitorTabScrollPane.setViewportView(getMonitorTabTree());
			
		}
		return monitorTabScrollPane;
	}

	/**
	 * This method initializes monitorTabDescScroll	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getMonitorTabDescScroll() {
		if (monitorTabDescScroll == null) {
			monitorTabDescScroll = new JScrollPane();
			monitorTabDescScroll.setViewportView(getMonitorTabDescTextArea());
		}
		return monitorTabDescScroll;
	}

	/**
	 * This method initializes monitorTabDescTextArea	
	 * 	
	 * @return javax.swing.JTextArea	
	 */
	private JEditorPane getMonitorTabDescTextArea() {
		if (monitorTabDescTextArea == null) {
			monitorTabDescTextArea = new JEditorPane();
			monitorTabDescTextArea.setEditable(false);
			monitorTabDescTextArea.setContentType("text/html");      // must specify HTML text
			monitorTabDescTextArea.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
			monitorTabDescTextArea.setFont(new Font("Arial", Font.PLAIN, 14));
		}
		return monitorTabDescTextArea;
	}

	/**
	 * This method initializes monitorTabTree	
	 * 	
	 * @return javax.swing.JTree	
	 */
	private JTree getMonitorTabTree() {
		if (monitorTabTree == null) {
			
			 root = new DefaultMutableTreeNode(new FixedTreeNode("AspectSense", "<i>Double click to expand/collapse </i>"));

			 componentsRoot =  new DefaultMutableTreeNode(new FixedTreeNode("Components", "<i>Double click to exapnd/collapse </i>"));
			 root.add(componentsRoot);
			 servicesRoot =  new DefaultMutableTreeNode(new FixedTreeNode("Services", "<i>Double click to exapnd/collapse </i>"));
			 root.add(servicesRoot);
			
			 myTreeModel = new DefaultTreeModel(root);
			 monitorTabTree = new JTree(myTreeModel);
			  
			 monitorTabTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
			 TreeListener treeListener = new TreeListener(monitorTabTree,getMonitorTabDescTextArea(),showTree, this);
			 monitorTabTree.addTreeSelectionListener(treeListener);
			
			
		}
		return monitorTabTree;
	}
	
	public void updateTree (HashMap<String, ITreeNode> treeNodes){
		
		Collection<ITreeNode> x = treeNodes.values();
		Iterator<ITreeNode> i = x.iterator();
		ITreeNode node;
	
		
		componentsRoot.removeAllChildren();
		servicesRoot.removeAllChildren();
		
		while (i.hasNext()){
			node = i.next();
			if (node instanceof ComponentTreeNode)
			{
				
				componentsRoot.add(new DefaultMutableTreeNode (node));
			}
			else if (node instanceof ServiceTreeNode)
			{
				
				servicesRoot.add(new DefaultMutableTreeNode (node));
			}
			
		}
		
		myTreeModel.reload();

	}

	/**
	 * This method initializes graphPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getGraphPanel() {
		if (graphPanel == null) {
			//graphPanel = new DrawGraph();
			graphPanel = new JPanel();
			graphPanel.setLayout(new GridBagLayout());
		}
		return graphPanel;
	}

	public static void rePaintGraph ()
	{
		graphPanel.repaint();
	}

	
	private JPanel getGraphOverviewPanel() {
		if (graphOverviewPanel == null) {
			graphOverviewPanel = new DrawOverviewGraph();
			//graphOverviewPanel.setPreferredSize(new Dimension(500,500));
			graphOverviewPanel.setLayout(new GridBagLayout());
		}
		return graphOverviewPanel;
	}

	public static void rePaintOverviewGraph ()
	{
		graphOverviewPanel.repaint();
	}



	/**
	 * This method initializes graphContainer	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getGraphContainer() {
		if (graphContainer == null) {
			graphContainer = new JPanel();
			graphContainer.setLayout(new BorderLayout());
			graphContainer.add(getGraphPanel(), BorderLayout.CENTER);
			graphContainer.add(getGraphTaskBar(), BorderLayout.SOUTH);
		}
		return graphContainer;
	}

	/**
	 * This method initializes graphOverviewContainer	
	 * 	which will include graphical representations
	 * of all installed components/services
	 * @return javax.swing.JPanel	
	 */
	private JPanel getGraphOverviewContainer() {
		if (graphOverviewContainer == null) {
			graphOverviewContainer = new JPanel();
			graphOverviewContainer.setLayout(new BorderLayout());
			graphOverviewContainer.setPreferredSize(new Dimension(2000,100));
			graphOverviewContainer.add(getGraphOverviewPanel(), java.awt.BorderLayout.CENTER);
			graphOverviewContainer.add(getGraphOverviewTaskBar(), BorderLayout.SOUTH);
			
		}
		return graphOverviewContainer;
	}


	/**
	 * This method initializes graphTaskBar	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getGraphTaskBar() {
		if (graphTaskBar == null) {
			graphTaskBar = new JPanel();
			graphTaskBar.setLayout(new BoxLayout(getGraphTaskBar(), BoxLayout.X_AXIS));
			graphTaskBar.add(getMaxPathsButton(), null);
			graphTaskBar.add(getRefreshButton(), null);
		}
		return graphTaskBar;
	}




	/**
	 * This method initializes maxPathsButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getMaxPathsButton() {
		if (maxPathsButton == null) {
			maxPathsButton = new JButton();
			maxPathsButton.setText("show paths");
		}
		/*maxPathsButton.addActionListener(new ActionListener (){

			@Override
			public void actionPerformed(ActionEvent e) {
				((DrawGraph) graphPanel).drawMaxPaths();
				
			}
			
		});*/
		return maxPathsButton;
	}




	/**
	 * This method initializes refreshButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getRefreshButton() {
		if (refreshButton == null) {
			refreshButton = new JButton();
			refreshButton.setText("refresh");
		}
		refreshButton.addActionListener(new ActionListener (){

				public void actionPerformed(ActionEvent e) {
				graphPanel.repaint();
			}
			
		});
		return refreshButton;
	}




	/**
	 * This method initializes showTree	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getShowTree() {
		
		if (showTree == null) {
			showTree = new JButton();
			showTree.setText("Show Tree");
			showTree.setEnabled(false);
		}
		
		showTree.addActionListener(new ActionListener (){

			@Override
			public void actionPerformed(ActionEvent e) {
				
				if (activeNode==null)
					System.out.println ("NULL active node");
				mainTabbedPane.addTab(activeNode.getName(), null, getGraphContainer(), "Runtime representation of available Services/Components");
				
			}
			
		});
		return showTree;
	}




	public void setActiveNode(ITreeNode treenode) {
		// TODO Auto-generated method stub
		this.activeNode=treenode;
	}




	/**
	 * This method initializes graphOverviewScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getGraphOverviewScrollPane() {
		if (graphOverviewScrollPane == null) {
			graphOverviewScrollPane = new JScrollPane();
			graphOverviewScrollPane.setViewportView(getGraphOverviewContainer());
		}
		return graphOverviewScrollPane;
	}




	/**
	 * This method initializes graphOverviewTaskBar	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getGraphOverviewTaskBar() {
		if (graphOverviewTaskBar == null) {
			graphOverviewTaskBar = new JPanel();
			graphOverviewTaskBar.setLayout(new BoxLayout(getGraphOverviewTaskBar(), BoxLayout.X_AXIS));
			graphOverviewTaskBar.add(getMaxPaths(), null);
		}
		return graphOverviewTaskBar;
	}




	/**
	 * This method initializes maxPaths	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getMaxPaths() {
		if (maxPaths == null) {
			maxPaths = new JButton();
			maxPaths.setText("max paths");
			maxPaths.addActionListener( new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent e) {
					((DrawOverviewGraph) graphOverviewPanel).drawMaxPaths();
					
					
				}
			});
		}
		return maxPaths;
	}
}
